import { _decorator, IVec2, Node, tween, Tween, Vec3 } from 'cc';
import { EntityTypeEnum, IBullet } from '../../Common';
import { EntityManager } from '../../Base/EntityManager';
import { EntityStateEnum, EventEnum } from '../../Enum';
import { rad2Angle } from '../../Utils';
import { BulletStateMachine } from './BulletStateMachine';
import EventManager from '../../Global/EventManager';
import DataManager from '../../Global/DataManager';
import { ExplosionMgr } from '../Explosion/ExplosionMgr';
import ObjectPoolManager from '../../Global/ObjectPoolManager';
const { ccclass, property } = _decorator;

@ccclass('BulletMgr')
export class BulletMgr extends EntityManager {
    type:EntityTypeEnum;
    id:number;
    private targetPos:Vec3;
    private tw:Tween<Node>;
    init(data:IBullet) {
        this.type = data.type;
        this.id = data.id;
        this.fsm = this.addComponent(BulletStateMachine);
        this.fsm.init(data.type);

        this.state = EntityStateEnum.Idle;
        
        this.node.active = false;
        this.targetPos = undefined;
        EventManager.Instance.on(EventEnum.ExplosionBorn,this.handleExplosionBorn,this);
    }

    handleExplosionBorn(id:number,{x,y}:IVec2) {
        if(this.id !== id) return;

        const explosion = ObjectPoolManager.Instance.get(EntityTypeEnum.Explosion);
        
        const em = explosion.getComponent(ExplosionMgr) || explosion.addComponent(ExplosionMgr);
        em.init(EntityTypeEnum.Explosion,{x,y});

        
        EventManager.Instance.off(EventEnum.ExplosionBorn,this.handleExplosionBorn,this);
        DataManager.Instance.bulletMap.delete(this.id);
        ObjectPoolManager.Instance.ret(this.node);
    }

    render(data:IBullet) {
        this.renderPos(data);
        this.renderDirection(data);
    }

    renderPos(data:IBullet) {
        const {position} = data;
        const newPos  = new Vec3(position.x,position.y);
        if(!this.targetPos)
        {
            this.node.active = true;
            this.node.setPosition(newPos);
            this.targetPos = newPos.clone();
        } 
        else if(!this.targetPos.equals(newPos))
        {
            this.node.setPosition(this.targetPos);
            this.targetPos.set(newPos)
            this.tw?.stop();
            this.tw = tween(this.node).to(0.1,{position:this.targetPos})
            .start();
        }
    }
    renderDirection(data:IBullet) {
        const {direction} = data;
        const size = Math.sqrt(direction.x * direction.x + direction.y * direction.y);
        const rad = Math.asin(direction.y / size);
        const angle = direction.x>0? rad2Angle(rad) : -rad2Angle(rad) + 180;

        this.node.setRotationFromEuler(0,0,angle);
    }
}


